#include "../includes/IPC.h"
#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
#include <string>
#include <vector>
#include <sstream> // for splitting file entries

int main() {
    const std::string socket_path = "/tmp/test_ipc.sock";
    IpcClient& client = IpcClient::getInstance(socket_path);

    std::cout << "Client starting, attempting to connect to server..." << std::endl;

    // 连接到服务器
    int conn_result = client.conn_to_server();
    if (conn_result == -1) {
        std::cerr << "Failed to connect to server." << std::endl;
        return 1;
    }
    std::cout << "Connected to server." << std::endl;

    std::atomic<bool> running(true); // 用于控制线程运行
    std::atomic<int> next_task_id(1); // 用于生成唯一的任务ID

    // --- 线程1: 发送任务 ---
    std::thread sender_thread([&client, &running, &next_task_id]() {
        int task_counter = 0; // 用于循环发送不同任务
        std::vector<std::string> test_files; // 用于存储写入的文件名，以便后续读取

        // 循环发送写任务和读任务
        for(int i = 0; i < 5; i++) { // 发送5对写/读任务
            std::string task_request;
            int task_id = next_task_id.fetch_add(1);

            // --- 发送写任务 ---
            std::string filename = "test_file_" + std::to_string(task_id) + ".txt";
            std::string content = "Content for task " + std::to_string(task_id) + " at iteration " + std::to_string(i);
            
            if (filename.length() > 128) {
                std::cerr << "Filename too long for write task." << std::endl;
                continue; // 跳过本次循环，尝试下一个
            }
            if (content.length() > 1024) {
                std::cerr << "Content too long for write task." << std::endl;
                continue; // 跳过本次循环，尝试下一个
            }

            char type_byte = static_cast<char>(0); // 写任务类型ID
            char filename_len_byte = static_cast<char>(filename.length());
            int32_t content_len_int = content.length();

            // 构建写任务内容 (不包含长度前缀)
            task_request.append(&type_byte, 1);
            task_request.append(&filename_len_byte, 1);
            task_request.append(filename);
            task_request.append(reinterpret_cast<const char*>(&content_len_int), 4);
            task_request.append(content);
            
            std::cout << "Sending Write Task (ID: " << task_id << ", File: " << filename << ", Content: " << content << ")" << std::endl;

            // 发送写任务 (遵循 [4字节长度][任务内容] 协议)
            if (!task_request.empty()) {
                int32_t task_len = task_request.length(); // 获取任务内容的长度
                
                // 1. 发送 4 字节长度
                int len_send_size = client.send_data(client.fd, sizeof(task_len), &task_len);
                if (len_send_size <= 0) {
                    std::cerr << "Failed to send write task length, code: " << len_send_size << std::endl;
                    running = false; // 通知其他线程退出
                    break;
                }

                // 2. 发送任务内容
                int content_send_size = client.send_data(client.fd, task_request.length(), task_request.data());
                if (content_send_size <= 0) {
                    std::cerr << "Failed to send write task content, code: " << content_send_size << std::endl;
                    running = false;
                    break;
                }

                std::cout << "Sent write task (ID: " << task_id << ") with total size: " << (sizeof(task_len) + task_request.length()) << " bytes." << std::endl;
            }

            task_request.clear(); // 清空 task_request 为下一次构建做准备
            task_id = next_task_id.fetch_add(1); // 为读任务获取新的ID

            // 模拟一点延迟，让写任务有时间处理
            std::this_thread::sleep_for(std::chrono::milliseconds(100));

            // --- 发送读任务 ---
            // 读取刚才写入的文件
            int32_t id_int = task_id;
            char type_byte_read = static_cast<char>(1); // 读任务类型ID
            char filename_len_byte_read = static_cast<char>(filename.length());

            task_request.append(reinterpret_cast<const char*>(&id_int), 4);
            task_request.append(&type_byte_read, 1);
            task_request.append(&filename_len_byte_read, 1);
            task_request.append(filename);
            
            std::cout << "Sending Read Task (ID: " << task_id << ", File: " << filename << ")" << std::endl;

            // 发送读任务 (遵循 [4字节长度][任务内容] 协议)
            if (!task_request.empty()) {
                int32_t task_len = task_request.length(); // 获取任务内容的长度
                
                // 1. 发送 4 字节长度
                int len_send_size = client.send_data(client.fd, sizeof(task_len), &task_len);
                if (len_send_size <= 0) {
                    std::cerr << "Failed to send read task length, code: " << len_send_size << std::endl;
                    running = false; // 通知其他线程退出
                    break;
                }

                // 2. 发送任务内容
                int content_send_size = client.send_data(client.fd, task_request.length(), task_request.data());
                if (content_send_size <= 0) {
                    std::cerr << "Failed to send read task content, code: " << content_send_size << std::endl;
                    running = false;
                    break;
                }

                std::cout << "Sent read task (ID: " << task_id << ") with total size: " << (sizeof(task_len) + task_request.length()) << " bytes." << std::endl;
            }

            // 模拟任务发送频率
            std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 降低频率
        }

        // 最后发送一个查看目录的任务
        std::string ls_task_request;
        int task_id = next_task_id.fetch_add(1);
        char type_byte_ls = static_cast<char>(4); // 查看目录任务类型ID
        ls_task_request.append(reinterpret_cast<const char*>(&task_id), 4);
        ls_task_request.append(&type_byte_ls, 1);
        
        std::cout << "Sending Ls Task (ID: " << task_id << ")" << std::endl;

        if (!ls_task_request.empty()) {
            int32_t task_len = ls_task_request.length();
            int len_send_size = client.send_data(client.fd, sizeof(task_len), &task_len);
            if (len_send_size <= 0) {
                std::cerr << "Failed to send ls task length, code: " << len_send_size << std::endl;
                running = false;
                return; // 直接从 lambda 返回
            }

            int content_send_size = client.send_data(client.fd, ls_task_request.length(), ls_task_request.data());
            if (content_send_size <= 0) {
                std::cerr << "Failed to send ls task content, code: " << content_send_size << std::endl;
                running = false;
                return; // 直接从 lambda 返回
            }

            std::cout << "Sent ls task (ID: " << task_id << ") with total size: " << (sizeof(task_len) + ls_task_request.length()) << " bytes." << std::endl;
        }

        std::cout << "Sender thread exiting." << std::endl;
    });

    // --- 线程2: 接收并打印结果 ---
    std::thread receiver_thread([&client, &running]() {
        std::string accumulated_data; // 用于处理TCP粘包

        while (running) {
            // --- 按协议接收响应 (假设服务端也使用长度前缀发送响应) ---
            // 先接收4字节长度
            int32_t resp_len;
            int len_recv_size = client.receive_data(client.fd, sizeof(resp_len), &resp_len);
            if (len_recv_size <= 0) {
                if (len_recv_size == 0) {
                    std::cout << "Server closed the connection." << std::endl;
                } else {
                    std::cerr << "Failed to receive response length, code: " << len_recv_size << std::endl;
                }
                running = false; // 通知其他线程退出
                break;
            }

            // 2. 根据长度接收响应内容
            if (resp_len < 0 || resp_len > 256 * 1024) { // 简单校验长度，防止恶意或错误数据
                std::cerr << "Invalid response length received: " << resp_len << std::endl;
                running = false; // 或者尝试恢复，这里选择停止
                break;
            }

            std::vector<char> content_buf(resp_len); // 使用 vector 避免手动管理内存
            int content_recv_size = client.receive_data(client.fd, resp_len, content_buf.data());
            if (content_recv_size <= 0) {
                if (content_recv_size == 0) {
                    std::cout << "Server closed the connection." << std::endl;
                } else {
                    std::cerr << "Failed to receive response content, code: " << content_recv_size << std::endl;
                }
                running = false;
                break;
            }

            if (content_recv_size != resp_len) {
                std::cerr << "Partial receive of response content, expected: " << resp_len 
                          << ", received: " << content_recv_size << std::endl;
                running = false;
                break;
            }

            // 3. 解析响应内容 (现在 content_buf.data() 包含了完整的响应字符串)
            std::string resp_content_str(content_buf.data(), content_recv_size);
            // --- 解析响应内容 (假设内容是 [任务ID(4字节) + 类型ID(1字节) + 状态码(1字节) + ...]) ---
            if (resp_content_str.length() < 6) { // 至少需要 4 + 1 + 1
                std::cerr << "Received response content is too short." << std::endl;
                continue; // 尝试继续接收下一个响应
            }

            size_t offset = 0;
            int task_id = *(reinterpret_cast<const int*>(resp_content_str.data() + offset));
            offset += 4;
            char type_id = resp_content_str[offset];
            offset += 1;
            char status_code = resp_content_str[offset];
            offset += 1;

            std::cout << "Received Response - Task ID: " << task_id << ", Type: " << static_cast<int>(type_id) 
                      << ", Status Code: " << static_cast<int>(status_code);

            std::string response_details = "";

            switch (type_id) {
                case 0: // 写文件响应: +4字节bytes_written
                    if (resp_content_str.length() >= offset + 4) {
                        int bytes_written = *(reinterpret_cast<const int*>(resp_content_str.data() + offset));
                        response_details = ", Bytes Written: " + std::to_string(bytes_written);
                    } else {
                        std::cerr << " [ERROR] Write response content is truncated." << std::endl;
                    }
                    break;
                case 1: // 读文件响应: +4字节content_length + 变长content
                    if (resp_content_str.length() >= offset + 4) {
                        int32_t content_len = *(reinterpret_cast<const int*>(resp_content_str.data() + offset));
                        if (resp_content_str.length() >= offset + 4 + content_len) {
                            std::string content_str = resp_content_str.substr(offset + 4, content_len);
                            response_details = ", Content Length: " + std::to_string(content_len) + ", Content: " + content_str;
                        } else {
                            std::cerr << " [ERROR] Cat response content is truncated." << std::endl;
                        }
                    } else {
                        std::cerr << " [ERROR] Cat response content is truncated." << std::endl;
                    }
                    break;
                case 2: // 创建文件响应: 无额外内容
                case 3: // 删除文件响应: 无额外内容
                    // No extra details to print beyond status code
                    break;
                case 4: // 查看目录响应: +1字节file_count + 变长file_entries
                    if (resp_content_str.length() >= offset + 1) {
                        char file_count = resp_content_str[offset];
                        offset += 1;
                        std::string entries_str = resp_content_str.substr(offset);
                        std::istringstream iss(entries_str);
                        std::string file_name;
                        std::vector<std::string> files;
                        while (std::getline(iss, file_name)) {
                            files.push_back(file_name);
                        }
                        response_details = ", File Count: " + std::to_string(static_cast<int>(file_count)) + ", Files: [";
                        for(size_t i = 0; i < files.size(); ++i) {
                            response_details += files[i];
                            if (i < files.size() - 1) response_details += ", ";
                        }
                        response_details += "]";
                    } else {
                        std::cerr << " [ERROR] Ls response content is truncated." << std::endl;
                    }
                    break;
                default:
                    std::cerr << " [ERROR] Unknown response type ID: " << static_cast<int>(type_id) << std::endl;
                    // 尝试继续，但可能数据已损坏
                    break;
            }

            std::cout << response_details << std::endl;
        }
        std::cout << "Receiver thread exiting." << std::endl;
    });

    // 等待两个线程结束
    if (sender_thread.joinable()) {
        sender_thread.join();
    }
    if (receiver_thread.joinable()) {
        receiver_thread.join();
    }

    // 关闭连接
    close(client.fd);

    std::cout << "Client shutting down." << std::endl;
    return 0;
}